package com.glodon.paas.activity.dao.mongo;

import java.util.List;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;

import com.glodon.paas.util.GenericsUtil;
import com.google.code.morphia.DatastoreImpl;
import com.google.code.morphia.query.Query;
import com.google.code.morphia.query.UpdateOperations;

@SuppressWarnings({ "unchecked" })
public class MongoDBDao<T, K> {

    protected Class<T>      entityClazz;

    @Autowired
    protected DatastoreImpl mongoDataStore;

    protected MongoDBDao() {
        entityClazz = GenericsUtil.getClazz(this.getClass());
    }

    public void ensureIndexes() {
        mongoDataStore.ensureIndexes(entityClazz);
    }

    @PostConstruct
    public void init() {
        mongoDataStore.getMapper().addMappedClass(entityClazz);
        this.ensureIndexes();
    }

    public void setEntityClazz(Class<T> entityClazz) {
        this.entityClazz = entityClazz;
    }

    public void save(T entity) {
        mongoDataStore.save(entity);
    }

    // @Override
    public T selectById(K id) {
        return mongoDataStore.get(entityClazz, id);
    }

    // @Override
    public K insert(T entity) {
        return (K) mongoDataStore.insert(entity).getId();
    }

    public int deleteById(K id) {
        return mongoDataStore.delete(entityClazz, id).getN();
    }

    public Query<T> createQuery() {
        return mongoDataStore.createQuery(entityClazz);
    }

    public UpdateOperations<T> createUpdateOperations() {
        return mongoDataStore.createUpdateOperations(entityClazz);
    }

    public int updateFirst(Query<T> q, UpdateOperations<T> ops) {
        return mongoDataStore.updateFirst(q, ops).getUpdatedCount();
    }

    public int deleteByQuery(Query<T> q) {
        return mongoDataStore.delete(q).getN();
    }

    public int update(Query<T> q, T entity) {
        return mongoDataStore.updateFirst(q, entity, false).getUpdatedCount();
    }

    public List<T> find(int fromIndex, int toIndex) {
        return mongoDataStore.find(entityClazz).asList().subList(fromIndex, toIndex);
    }
}
